#pragma once 

#include <stdarg.h>
#include <iostream>
#include <time.h>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


using namespace std;

#define SIZE 1024

#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4

#define Screen 1    // 往屏幕打印
#define Onefile 2   // 往一个文件打印
#define Classfile 3 // 分文件打印

const char *filename = "log.txt";

string LevelToTtring(int level)
{
    switch (level)
    {
    case Info:
        return "Info";
    case Debug:
        return "Debug";
    case Warning:
        return "Warning";
    case Error:
        return "Error";
    case Fatal:
        return "Fatal";
    default:
        return "None";
    }
}

class Log
{
public:
    Log()
    {
        printMethod = Screen;
        path = "./log.txt";
    }

    // void logmessage(int level, const char *format, ...)
    // {
    //     time_t t = time(NULL);
    //     struct tm *ctime = localtime(&t);

    //     char leftbuffer[SIZE] = {0};
    //     snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d-%d-%d]", LevelToTtring(level).c_str(),
    //              ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

    //     char rightbuffer[SIZE] = {0};
    //     va_list s;
    //     va_start(s, format);
    //     vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
    //     va_end(s);

    //     char logbuffer[SIZE * 2] = {0};
    //     snprintf(logbuffer, sizeof(logbuffer), "%s %s", leftbuffer, rightbuffer);

    //     PrintLog(level,logbuffer);
    // }

    void PrintLog(int level, const string &logtxt)
    {
        switch (printMethod)
        {
        case Screen:
            cout<<logtxt<<endl;
            break;
        case Onefile:
            printOneFile(filename, logtxt);
            break;
        case Classfile:
            printClassFile(level,logtxt);
            break;
        default:
            break;
        }
    }

    void printOneFile(const string &filename, const string &logtxt)
    {
        int fd=open(filename.c_str(), O_APPEND|O_CREAT|O_WRONLY);
        if(fd<0)    return ;
        write(fd,logtxt.c_str(),logtxt.size());
    }

    void printClassFile(int level,const string &logtxt)
    {
        string file=path+"."+LevelToTtring(level);
        printOneFile(file,logtxt);
    }

    void operator()(int level, const char *format, ...)
    {
        time_t t = time(NULL);
        struct tm *ctime = localtime(&t);

        char leftbuffer[SIZE] = {0};
        snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d-%d-%d]", LevelToTtring(level).c_str(),
                 ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        char rightbuffer[SIZE] = {0};
        va_list s;
        va_start(s, format);
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);

        char logbuffer[SIZE * 2] = {0};
        snprintf(logbuffer, sizeof(logbuffer), "%s %s", leftbuffer, rightbuffer);

        PrintLog(level,logbuffer);
    }


private:
    int printMethod; // 打印方法
    string path;     // 文件路径
};



int sum(int n, ...)
{
    va_list s; // char*
    va_start(s, n);

    int sum = 0;
    while (n)
    {
        sum += va_arg(s, int); // printf("hello %d, hello %s, hello %c, hello %d,", 1, "hello", 'c', 123);
        n--;
    }

    va_end(s); // s = NULL
    return sum;
}